using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Globalization;

using SeeqSharp;

namespace SeeqDownloader
{
    public partial class SearchForm : Form
    {
        private Playlist lastPlaylist;
        private bool searchEmpty = true;

        public SearchForm()
        {
            InitializeComponent();
        }

        private Track SelectedTrack
        {
            get
            {
                if (resultsListView.SelectedIndices.Count == 0)
                    return null;

                return (lastPlaylist.TrackList[resultsListView.SelectedIndices[0]]);
            }
        }

        public IEnumerable<Track> SelectedTracks
        {
            get
            {
                for (int i = 0; i < resultsListView.SelectedIndices.Count; i++)
                {
                    yield return lastPlaylist.TrackList[resultsListView.SelectedIndices[i]];
                }
            }
        }

        private void Search()
        {
            resultsListView.Items.Clear();
            searchTextBox.Enabled = false;
            searchButton.Enabled = false;
            statusLabel.Text = "Searching...";

            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                if (searchTextBox.Text.StartsWith("http://www.seeqpod.com/search/?plid=") == true)
                    this.lastPlaylist = Playlist.FromPlaylistUrl(searchTextBox.Text);
                else
                    this.lastPlaylist = Playlist.Search(searchTextBox.Text);
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    searchTextBox.Enabled = true;
                    searchButton.Enabled = true;
                    statusLabel.Text = string.Format("Found {0} items.", this.lastPlaylist.TrackList.Count);

                    foreach (Track track in this.lastPlaylist.TrackList)
                    {
                        resultsListView.Items.Add(new ListViewItem(new string[] { track.ToString(), track.Location }));
                    }
                });
            });
        }

        private void resultsListView_DoubleClick(object sender, EventArgs e)
        {
            Track currentTrack = this.SelectedTrack;
            statusLabel.Text = "Fetching download url for " + currentTrack.Creator + " - " + currentTrack.Title + "...";

            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                string downloadUri = currentTrack.GetDownloadUri();
                if (downloadUri == null)
                {
                    this.BeginInvoke((MethodInvoker)delegate()
                    {
                        statusLabel.Text = "No download Uri available for " + currentTrack.Creator + " - " + currentTrack.Title + ".";
                    });
                    return;
                }
                Process.Start(downloadUri);
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    statusLabel.Text = "Idle.";
                });
            });
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            this.Search();
        }

        private void resultsListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                resultsContextMenu.Show(resultsListView, e.Location);
        }

        private void copyLocationToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Track currentTrack = this.SelectedTrack;
            Clipboard.SetText(currentTrack.Location);
            statusLabel.Text = "Copied location of " + currentTrack.Creator + " - " + currentTrack.Title + " to clipboard.";
        }

        private void copyDownloadUriToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Track currentTrack = this.SelectedTrack;
            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                string downloadUri = currentTrack.GetDownloadUri();
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    Clipboard.SetText(downloadUri);
                    statusLabel.Text = "Copied download uri of " + currentTrack.Creator + " - " + currentTrack.Title + " to clipboard.";
                });
            });
        }

        private void searchTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                e.Handled = true;
                this.Search();
            }
        }

        private void SearchForm_Resize(object sender, EventArgs e)
        {
            searchTextBox.Size = new Size(toolStrip1.Bounds.Width - toolStrip1.GripMargin.Horizontal - searchButton.Bounds.Width, searchTextBox.Height);
        }

        private void SearchForm_Load(object sender, EventArgs e)
        {
            searchTextBox.Size = new Size(toolStrip1.Bounds.Width - toolStrip1.GripMargin.Horizontal - searchButton.Bounds.Width, searchTextBox.Height);
        }

        private void SearchForm_Shown(object sender, EventArgs e)
        {
            searchTextBox.Focus();
        }

        private void searchTextBox_Enter(object sender, EventArgs e)
        {
            if (this.searchEmpty == true)
            {
                this.searchEmpty = false;
                searchTextBox.ForeColor = SystemColors.WindowText;
                searchTextBox.Text = "";
            }
        }

        private void searchTextBox_Leave(object sender, EventArgs e)
        {
            if (searchTextBox.Text == "")
            {
                this.searchEmpty = true;
                searchTextBox.ForeColor = Color.Gray;
                searchTextBox.Text = "Search anything, or enter a playlist url here...";
            }
        }

        private void downloadAllSelectedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.Description = "Choose the directory you want to save the files...";
            if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
                return;

            downloadsList.BeginUpdate();
            foreach (Track track in this.SelectedTracks)
            {
                string downloadTitle = track.Creator + " - " + track.Title;
                string downloadFile = Path.Combine(folderBrowserDialog1.SelectedPath, downloadTitle + ".mp3");

                DownloadListItem downloadListItem = new DownloadListItem(track);
                downloadsList.Items.Add(downloadListItem);
                
                WebClient client = new WebClient();
                client.DownloadProgressChanged += delegate(object state, DownloadProgressChangedEventArgs args)
                {
                    double percentage = ((double)args.BytesReceived / (double)args.TotalBytesToReceive);
                    
                    downloadListItem.Progress = percentage;
                    downloadsList.Refresh();
                };
                client.DownloadFileCompleted += delegate(object state, AsyncCompletedEventArgs args)
                {
                    downloadsList.Items.Remove(downloadListItem);
                };
                ThreadPool.QueueUserWorkItem(delegate(object state)
                {
                    string downloadUrl = track.GetDownloadUri();
                    //downloadUrl = track.Location;
                    this.BeginInvoke((MethodInvoker)delegate()
                    {
                        client.DownloadFileAsync(new Uri(downloadUrl), downloadFile);
                    });
                });
            }
            downloadsList.EndUpdate();
        }
    }
}